<template>
  <div class="compiler-container">
    <div class="editor-header">
      <select v-model="language" class="language-select">
        <option value="javascript">JavaScript</option>
        <!-- <option value="python">Python</option>
        <option value="java">Java</option> -->
        <option value="html">HTML</option>
        <!-- <option value="css">CSS</option> -->
      </select>
      <button class="run-btn" @click="runCode">运行</button>
    </div>
    <div class="editor-container" ref="editorContainer"></div>
    <div class="output-container">
      <div class="output-header">输出结果：</div>
      <iframe v-if="language === 'html'" ref="outputFrame" class="output-frame"></iframe>
      <div v-else class="output-content" v-html="output"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import loader from '@monaco-editor/loader'

const editorContainer = ref<HTMLElement | null>(null)
const language = ref('javascript')
const output = ref('')
const outputFrame = ref<HTMLIFrameElement | null>(null)
let editor: any = null
let monaco: any = null

// 配置 CDN 路径
loader.config({
  paths: {
    vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.43.0/min/vs'
  }
})
// 初始代码模板
const getInitialCode = (lang: string) => {
  const templates: { [key: string]: string } = {
    javascript: '// 在这里输入 JavaScript 代码\nconsole.log("Hello World!");',
    // python: '# 在这里输入 Python 代码\nprint("Hello World!")',
    // java: '// 在这里输入 Java 代码\npublic class Main {\n    public static void main(String[] args) {\n        System.out.println("Hello World!");\n    }\n}',
    html: '<!-- 在这里输入 HTML 代码 -->\n<!DOCTYPE html>\n<html>\n<head>\n    <title>Hello</title>\n</head>\n<body>\n    <h1>Hello World!</h1>\n</body>\n</html>',
    // css: '/* 在这里输入 CSS 代码 */\nbody {\n    background-color: #f0f0f0;\n    color: #333;\n}'
  }
  return templates[lang] || '// 开始编码'
}

// 运行代码
const runCode = () => {
  if (!editor) return
  const code = editor.getValue()
  try {
    switch (language.value) {
      case 'javascript':
        let consoleOutput = ''
        const originalConsoleLog = console.log
        console.log = (...args) => {
          consoleOutput += args.join(' ') + '\n'
        }
        eval(code)
        console.log = originalConsoleLog
        output.value = consoleOutput || '代码执行成功，但没有输出'
        break
      case 'html':
        if (outputFrame.value) {
          const frameDoc = outputFrame.value.contentDocument
          if (frameDoc) {
            frameDoc.open()
            frameDoc.write(code)
            frameDoc.close()
          }
        }
        break
      default:
        output.value = '目前只支持 JavaScript 和 HTML 代码运行'
    }
  } catch (error: any) {
    output.value = `错误: ${error.message}`
  }
}

onMounted(async () => {
  try {
    monaco = await loader.init()
    
    if (editorContainer.value) {
      editor = monaco.editor.create(editorContainer.value, {
        value: getInitialCode(language.value),
        language: language.value,
        theme: 'vs-dark',
        minimap: { enabled: false },
        automaticLayout: true,
        fontSize: 14,
        lineNumbers: 'on',
        scrollBeyondLastLine: false,
        roundedSelection: false,
        readOnly: false,
        tabSize: 2,
        wordWrap: 'on'
      })
    }
  } catch (error) {
    console.error('Monaco Editor 加载失败:', error)
  }
})

// 监听语言变化
watch(language, (newLang) => {
  if (editor && monaco) {
    const model = editor.getModel()
    monaco.editor.setModelLanguage(model, newLang)
    editor.setValue(getInitialCode(newLang))
  }
})

// 组件销毁时清理编辑器
onBeforeUnmount(() => {
  if (editor) {
    editor.dispose()
  }
})
</script>

<style scoped>
.compiler-container {
  width: 100%;
  height: 85%;
  display: flex;
  flex-direction: column;
  border: 1px solid #333;
  border-radius: 4px;
  background-color: #1e1e1e;
  color: #e0e0e0;
}

.editor-header {
  padding: 8px;
  border-bottom: 1px solid #333;
  display: flex;
  gap: 10px;
  background-color: #252525;
}

.language-select {
  padding: 4px 8px;
  border-radius: 4px;
  background-color: #2d2d2d;
  color: #e0e0e0;
  border: 1px solid #404040;
  outline: none;
}

.language-select:focus {
  border-color: #0078d4;
}

.language-select option {
  background-color: #2d2d2d;
  color: #e0e0e0;
}

.run-btn {
  padding: 4px 12px;
  background-color: #0078d4;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.run-btn:hover {
  background-color: #0086f0;
}

.run-btn:active {
  background-color: #006cbd;
}

.editor-container {
  flex: 1;
  min-height: 300px;
}

.output-container {
  border-top: 1px solid #333;
  padding: 8px;
  background-color: #252525;
  display: flex;
  flex-direction: column;
}

.output-header {
  font-weight: bold;
  margin-bottom: 8px;
  color: #e0e0e0;
}

.output-content {
  font-family: 'Consolas', monospace;
  white-space: pre-wrap;
  padding: 8px;
  background-color: #1e1e1e;
  border-radius: 4px;
  min-height: 100px;
  border: 1px solid #333;
  color: #e0e0e0;
  overflow: auto;
  max-height: 200px;
}

.output-frame {
  width: 100%;
  /* min-height: 200px; */
  border: 1px solid #333;
  border-radius: 4px;
  background-color: white;
}
</style>